package com.dong.web.clazz.bean;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import com.dong.web.annotation.Auto;
import com.dong.web.annotation.Transaction;
import com.dong.web.clazz.ClazzHandler;
import com.dong.web.database.Connected;
import com.dong.web.proxy.ProxyHandler;

public class ABean {

	private String url;

	private boolean singleton = true;

	private Method[] methods = null;

	private Class<?> clazz = null;

	private Object object = null;

	private Map<String, Method> actionMethods = null;

	private List<Field> fields = null;

	public Map<String, Method> getActionMethods() {
		return actionMethods;
	}

	public void setActionMethods(Map<String, Method> actionMethods) {
		this.actionMethods = actionMethods;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public boolean isSingleton() {
		return singleton;
	}

	public void setSingleton(boolean singleton) {
		this.singleton = singleton;
	}

	public Method[] getMethods() {
		return methods;
	}

	public void setMethods(Method[] methods) {
		this.methods = methods;
	}

	public Class<?> getClazz() {
		return clazz;
	}

	public void setClazz(Class<?> clazz) {
		this.clazz = clazz;
	}

	public Object getObject() {
		if ((object == null || !singleton) && clazz != null) {
			try {
				object = clazz.newInstance();
				if (fields != null) {
					for (Field field : fields) {
						Auto auto = field.getAnnotation(Auto.class);
						String key = null;
						if (auto.value().length() > 0) {
							key = auto.value();
						} else {
							key = field.getType().getName();
						}
						field.setAccessible(true);
						if (ClazzHandler.DONG_BEAN.containsKey(key)) {
							field.set(object, ClazzHandler.DONG_BEAN.get(key)
									.getObject());
						} else {
							for (Map.Entry<String, SBean> entry : ClazzHandler.SERVICE_BEAN
									.entrySet()) {
								String eKey = entry.getKey();
								if (Arrays.asList(eKey.split(","))
										.contains(key)) {
									Class<?> serviceClazz = entry.getValue()
											.getClazz();
									Method[] serviceMethods = serviceClazz
											.getDeclaredMethods();
									boolean isTransaction = false;
									for (Method serviceMethod : serviceMethods) {
										if (serviceMethod
												.isAnnotationPresent(Transaction.class)) {
											Transaction transaction = serviceMethod
													.getAnnotation(Transaction.class);
											if (transaction.value()) {
												isTransaction = true;
												break;
											}
										}
									}
									if (isTransaction) {
										field.set(object, new ProxyHandler()
												.bind(entry.getValue()
														.getObject()));
									} else {
										field.set(object, entry.getValue()
												.getObject());
										Connected.clearThreadLocal();
									}
									break;
								}
							}
						}
					}
				}
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return object;
	}

	public List<Field> getFields() {
		return fields;
	}

	public void setFields(List<Field> fields) {
		this.fields = fields;
	}

}
